package com.zebra.common.concurrent;



import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ZebraScheduler {
    private ZebraFixedTimeScheduler scheduler;

    public ZebraScheduler(){
        this(50);
    }

    public ZebraScheduler(int corePoolSize) {
        scheduler = new ZebraFixedTimeScheduler(corePoolSize, "zebra-scheduler");
    }

    /**
     * 定时
     * @param command
     * @param delay
     * @param unit
     * @param executor
     * @return
     */
    public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit, Executor executor) {
        if (executor == null) {
            return scheduler.schedule(command, delay, unit);
        } else {
            return scheduler.schedule(() -> executor.execute(command), delay, unit);
        }
    }





    /**
     * 定时循环
     * @param command
     * @param initDelay
     * @param period
     * @param unit
     * @param executor
     * @return
     */
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initDelay,
                                                  long period,
                                                  TimeUnit unit,
                                                  Executor executor) {
        if (executor == null) {
            return scheduler.scheduleAtFixedRate(command, initDelay, period, unit);
        } else {
            return scheduler.scheduleAtFixedRate(() -> executor.execute(command), initDelay,
                    period, unit);
        }
    }



    /**
     * 定时循环 延时
     * @param command
     * @param initDelay
     * @param delay
     * @param unit
     * @param executor
     * @return
     */
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initDelay,
                                                     long delay,
                                                     TimeUnit unit,
                                                     Executor executor) {
        if (executor == null) {
            return scheduler.scheduleWithFixedDelay(command, initDelay, delay, unit);
        } else {
            return scheduler.scheduleWithFixedDelay(() -> executor.execute(command), initDelay,
                    delay, unit);
        }
    }


    /**
     * 固定循环
     * @param command
     * @param initDelay
     * @param delay
     * @param repeat 次数 +1
     * @param unit
     * @param executor
     * @return
     */
    public ScheduledFuture<?> scheduleWithFixedTime(Runnable command,
                                                    long initDelay,
                                                    long delay,
                                                    int repeat,
                                                    TimeUnit unit,
                                                    Executor executor) {
        if (executor == null) {
            return scheduler.scheduleWithFixedTime(command, initDelay, delay, repeat, unit);
        } else {
            return scheduler.scheduleWithFixedTime(() -> executor.execute(command), initDelay,
                    delay, repeat, unit);
        }
    }


    public static boolean cancelScheduled(ScheduledFuture<?> stepFuture) {
        if (stepFuture != null) {
            if (stepFuture.isCancelled() || stepFuture.isDone()) {
                return true;
            } else {
                boolean result = stepFuture.cancel(false);
                return result;
            }
        }
        return true;
    }


    public void shutdown() {
        scheduler.shutdown();
    }

    public void shutdownNow(){
        scheduler.shutdownNow();
    }

}
